﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Threading;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices.ComTypes;
using IDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;

namespace FicusFactor.Watermarker
{
    /// <summary>
    /// Base class for callbacks from WLPG to perform work
    /// </summary>
    [ComVisible(true)]
    public abstract class WatermarkerBase : IDropTarget, IDisposable
    {
        private BackgroundWorker worker = new BackgroundWorker();

        [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass")]
        [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out] StringBuilder lpszFile, uint cch);

        public IList<string> Files
        {
            get;
            private set;
        }

        protected BackgroundWorker Worker
        {
            get
            {
                return worker;
            }
        }

        #region IDropTarget Members

        public virtual void DragEnter(IDataObject dataObject, uint keyState, Point pt, ref uint effect)
        {
            effect = 0x1; // DROPEFFECT_COPY
        }

        public virtual void DragOver(uint keyState, Point pt, ref uint effect)
        {
        }

        public virtual void DragLeave()
        {
        }

        public virtual void Drop(IDataObject dataObject, uint keyState, Point pt, ref uint effect)
        {
            List<string> files = new List<string>();
            STGMEDIUM medium = new STGMEDIUM();
            FORMATETC format = new FORMATETC();

            try
            {
                effect = 0x1; // DROPEFFECT_COPY

                format.cfFormat = 15; // CF_HDROP
                format.dwAspect = DVASPECT.DVASPECT_CONTENT;
                format.lindex = -1;
                format.tymed = TYMED.TYMED_HGLOBAL;

                Marshal.ThrowExceptionForHR(dataObject.QueryGetData(ref format));
                dataObject.GetData(ref format, out medium);

                uint fileCount = DragQueryFile(medium.unionmember, 0xffffffff, null, 0);
                for (uint i = 0; i < fileCount; i++)
                {
                    StringBuilder fileName = new StringBuilder(255);
                    DragQueryFile(medium.unionmember, i, fileName, (uint)fileName.MaxCapacity);
                    files.Add(fileName.ToString());
                }

                Files = files;

                if (files.Count == 0)
                {
                    MessageBox.Show("Must select one or more files from Windows Live Photo Gallery", "No files selected!", MessageBoxButtons.OKCancel);
                }
            }
            finally
            {
                if (medium.unionmember != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(medium.unionmember);
                }
            }
        }

        #endregion

        protected WatermarkerBase()
        {
            worker.DoWork += DoWork;
            worker.RunWorkerCompleted += OnWorkerCompleted;
        }

        protected virtual void OnWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
        }

        protected virtual void DoWork(object sender, DoWorkEventArgs e)
        {
        }

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (true == disposing)
            {
                if (null != worker)
                {
                    worker.Dispose();
                }
            }
        }

        #endregion
    }
}